package com.xywy.common.util.ble.util;

import java.util.List;
import java.util.UUID;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.BluetoothManager;
import android.bluetooth.BluetoothProfile;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.util.Log;
import android.widget.Toast;

import com.xywy.common.util.ble.common.CommonAttr;
import com.xywy.wjk.util.WjkConstant;

/**
 * single 必须调用init(context) 方法； Created by yangyu on 14-10-21.
 */
public class BLEBloodPresureProvider {
	private static final String TAG = "BLEUtils";

	public final static String ACTION_GATT_CONNECTED = "com.example.bluetooth.ledd.ACTION_GATT_CONNECTED";
	public final static String ACTION_GATT_DISCONNECTED = "com.example.bluetooth.ledd.ACTION_GATT_DISCONNECTED";
	public final static String ACTION_GATT_SERVICES_DISCOVERED = "com.example.bluetooth.ledd.ACTION_GATT_SERVICES_DISCOVERED";
	public final static String ACTION_DATA_AVAILABLE = "com.example.bluetooth.ledd.ACTION_DATA_AVAILABLE";
	public final static String ACTION_READ_CHARACTERISTIC = "com.example.bluetooth.ledd.ACTION_READ_CHARACTERISTIC";
	public final static String ACTION_SYSTEMID = "com.example.bluetooth.ledd.ACTION_SYSTEMID";// 传递SystemID
	public final static String ACTION_WEIGHT_DATA = "com.example.bluetooth.ledd.ACTION_WEIGHT_DATA";// 传递体重数据
	public final static String ACTION_XUEYA_DATA = "com.example.bluetooth.ledd.ACTION_XUEYA_DATA";// 传递体重数据
	public final static String EXTRA_DATA = "com.example.bluetooth.ledd.EXTRA_DATA";

	public final static String ACTION_WRITE_DATA_AVAILABLE = "com.example.bluetooth.ledd.ACTION_WRITE_DATA_AVAILABLE";
	/*
	 * 当前设备的连接状态；
	 */
	public static final int REQUEST_ENABLE_BT = 1;
	public static final int STATE_DISCONNECTED = 0;
	public static final int STATE_CONNECTING = 1;
	public static final int STATE_CONNECTED = 2;

	/**
	 * 血压计连接的唯一UUID
	 */
	public final static UUID UUID_HEART_RATE_MEASUREMENT = UUID.fromString("00001810-0000-1000-8000-00805f9b34fb");

	private static BLEBloodPresureProvider utils = new BLEBloodPresureProvider();
	private Context context;
	private BluetoothAdapter mBluetoothAdapter;
	private BluetoothManager mBluetoothManager;
	private String mBluetoothDeviceAddress;
	private BluetoothGatt mBluetoothGatt;
	private BluetoothDevice curDevice;
	private int mConnectionState = STATE_DISCONNECTED;

	private BLEBloodPresureProvider() {

	}

	public static BLEBloodPresureProvider getInstance() {
		return utils;
	}

	public static void DisconnectAndCreateNewInstance() {
		utils.disconnect();
		utils.close();
		utils = new BLEBloodPresureProvider();
	}

	/**
	 * 如果要使用蓝牙工具类，必须调用此方法
	 * 
	 * @param context
	 * @return
	 */
	public boolean init(Context context) {
		this.context = context;
		initReceiver();
		if (!context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
			Toast.makeText(context, "不支持设备", Toast.LENGTH_SHORT).show();
			return false;
		}
		// Initializes Bluetooth adapter.

		if (mBluetoothManager == null) {
			mBluetoothManager = (BluetoothManager) context.getSystemService(Context.BLUETOOTH_SERVICE);
		}
		if (mBluetoothAdapter == null) {
			mBluetoothAdapter = mBluetoothManager.getAdapter();
		}
		openBLE();

		return true;
	}

	/**
	 * 直接打开蓝牙
	 */
	public void openBLE() {

		if (mBluetoothAdapter != null || !mBluetoothAdapter.isEnabled()) {
			// Toast.makeText(context, "正在打开蓝牙", Toast.LENGTH_SHORT).show();
			mBluetoothAdapter.enable();
		}
	}

	public BluetoothAdapter getBLEAdatper() {
		return mBluetoothAdapter;
	}

	// Various callback methods defined by the BLE API.
	private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {

		@Override
		public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
			String intentAction;
			if (newState == BluetoothProfile.STATE_CONNECTED) {
				intentAction = ACTION_GATT_CONNECTED;
				mConnectionState = STATE_CONNECTED;
				Log.e("血压 血压----", "已经连接到血压");
				broadcastUpdate(intentAction);
				Log.i(TAG, "Attempting to start service discovery:"
						+ mBluetoothGatt.discoverServices());
			} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
				Log.e("血压血呀啊呀呀呀呀", "断开连接-----");
				intentAction = ACTION_GATT_DISCONNECTED;
				mConnectionState = STATE_DISCONNECTED;
				broadcastUpdate(intentAction);
				if(mIntent != null){
					Log.e("血压", "发送体温连接广播连接-----");
					context.sendBroadcast(mIntent);
					mIntent = null;
				}
				//新家上的
				close();
			}
		}

		@Override
		// New services discovered
		public void onServicesDiscovered(BluetoothGatt gatt, int status) {
			if (status == BluetoothGatt.GATT_SUCCESS) {
				Log.e("fasongle", "3333333333333333333333333333333");
				broadcastUpdate(ACTION_GATT_SERVICES_DISCOVERED);
			} else {
			}
		}

		@Override
		// Result of a characteristic read operation
		public void onCharacteristicRead(BluetoothGatt gatt, final BluetoothGattCharacteristic characteristic, int status) {
			System.out.println("血压---onCharacteristicRead--  ");
			byte [] temp = characteristic.getValue();
			if(temp != null){
//				System.out.printf("\n\r");
//				for(int i=0;i<temp.length;i++){
//					byte temp_byte = temp[i];
//					System.out.printf("%02x ",temp_byte);
//				}
//				System.out.printf("\n\r");
				
				if(temp.length>=2){
					if((temp[2]&0x2f) != 0x00){
						Log.e("missss---", "现在错误了");
						Intent intent = new Intent(WjkConstant.CONNECT_BLOOD_RESTART);
						context.sendBroadcast(intent);
						disconnect();
					}
				}
			}
			if (status == BluetoothGatt.GATT_SUCCESS) {
				if (characteristic.getUuid().toString().equals(CommonAttr.WeightScale.BLE_DEVICE_INFO_CHAR)) { // 传递设备id
					broadcastUpdate(ACTION_SYSTEMID, characteristic);
				} else if (characteristic.getUuid().toString().equals(CommonAttr.Sphygmomanometer.SERVICE_CHARACTERISTIC_RECEIVE)) {
					broadcastUpdate(ACTION_XUEYA_DATA, characteristic);
				} else {
					broadcastUpdate(ACTION_READ_CHARACTERISTIC, characteristic);
				}
			}

		}

		@Override
		public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {

			if (characteristic.getUuid().toString().equals(CommonAttr.WeightScale.BLE_SWAP_DATA_CHAR)) {
				broadcastUpdate(ACTION_WEIGHT_DATA, characteristic); // 传递体重数据
			} else {
				broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
			}

		}

		public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {

			broadcastUpdate(ACTION_WRITE_DATA_AVAILABLE, characteristic);
		};

	};

	private void broadcastUpdate(final String action) {
		final Intent intent = new Intent(action);
		context.sendBroadcast(intent);
	}

	private void broadcastUpdate(final String action, final BluetoothGattCharacteristic characteristic) {
		// final Intent intent = new Intent(action);
		Intent intent = new Intent(action);
		if (CommonAttr.Sphygmomanometer.SERVICE_CHARACTERISTIC_RECEIVE.equals(characteristic.getUuid().toString())) { // 接受
			intent.putExtra(EXTRA_DATA, characteristic.getValue());
		} else if (CommonAttr.Sphygmomanometer.SERVICE_CHARACTERISTIC_SEND.equals(characteristic.getUuid().toString())) {// 传递相应的数据出去，
																															// 接受广播处理
																															// Log.d(TAG,
																															// "走的是send通道");
		} else if (CommonAttr.WeightScale.BLE_DEVICE_INFO_CHAR.equals(characteristic.getUuid().toString())) { // 传递相应的数据出去，
			// Log.d(TAG, "走的是SystemID通道"); // 接受广播处理

			intent.putExtra(EXTRA_DATA, characteristic.getValue());
		} else if (CommonAttr.WeightScale.BLE_SWAP_DATA_CHAR.equals(characteristic.getUuid().toString())) {
			intent.putExtra(EXTRA_DATA, characteristic.getValue());
		} else {
			// Log.d(TAG, "不是我需要的通道");
		}
		final byte[] data = characteristic.getValue();
		if (data != null && data.length > 0) {
			final StringBuilder stringBuilder = new StringBuilder(data.length);
			for (byte byteChar : data)
				stringBuilder.append(String.format("%02X ", byteChar));
		}
		context.sendBroadcast(intent);
	}

	/**
	 * 发送消息通知蓝牙设备
	 * 
	 * @param characteristic
	 *            修改value后的char
	 */
	public boolean writeCharacteristic(BluetoothGattCharacteristic characteristic) {
		if (mBluetoothAdapter == null || mBluetoothGatt == null) {
			return false;
		}
		return mBluetoothGatt.writeCharacteristic(characteristic);
	}

	/**
	 * 读取指定的characteristic。
	 * 
	 * @param characteristic
	 *            The characteristic to read from.
	 */
	public void readCharacteristic(BluetoothGattCharacteristic characteristic) {
		if (mBluetoothAdapter == null || mBluetoothGatt == null) {
			return;
		}
		mBluetoothGatt.readCharacteristic(characteristic);
	}

	public BluetoothGatt getBluetoothGatt() {
		return mBluetoothGatt;
	}

	/**
	 * 设置当指定characteristic值变化时，发出通知。
	 * 
	 * @param characteristic
	 *            Characteristic to act on.
	 * @param enabled
	 *            If true, enable notification. False otherwise.
	 */
	public void setCharacteristicNotification(BluetoothGattCharacteristic characteristic, boolean enabled) {
		if (mBluetoothAdapter == null || mBluetoothGatt == null) {
			return;
		}
		mBluetoothGatt.setCharacteristicNotification(characteristic, enabled);

	}

	/**
	 * 获取设备当前所有的Service
	 * 
	 * @return A {@code List} of supported services.
	 */
	public List<BluetoothGattService> getSupportedGattServices() {
		if (mBluetoothGatt == null)
			return null;

		return mBluetoothGatt.getServices();
	}

	/**
	 * 获取指定的Service
	 * 
	 * @param uuid
	 * @return
	 */
	public BluetoothGattService getGattService(String uuid) {
		if (mBluetoothGatt == null)
			return null;
		for (BluetoothGattService service : mBluetoothGatt.getServices()) {
			if (service.getUuid().toString().equals(uuid)) {
				return service;
			}
		}
		return null;
	}

	/**
	 * 通过Address 连接蓝牙设备；
	 * 
	 * @param address
	 *            The device address of the destination device.
	 * @return Return true if the connection is initiated successfully. The
	 *         connection result is reported asynchronously through the
	 *         {@code BluetoothGattCallback#onConnectionStateChange(android.bluetooth.BluetoothGatt, int, int)}
	 *         callback.
	 */
	public boolean connect(final String address) {
		if (mBluetoothAdapter == null || address == null) {
			return false;
		}

		// Previously connected device. Try to reconnect.
		if (mBluetoothDeviceAddress != null && address.equals(mBluetoothDeviceAddress) && mBluetoothGatt != null) {
			if (mBluetoothGatt.connect()) {
				mConnectionState = STATE_CONNECTING;
				return true;
			} else {
				mConnectionState = STATE_DISCONNECTED;
				return false;
			}
		}

		final BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
		if (device == null) {
			return false;
		}
		// We want to directly connect to the device, so we are setting the
		// autoConnect
		// parameter to false.
		mBluetoothGatt = device.connectGatt(context, false, mGattCallback); // 是否自动连接，
		// 连接成功后会调用此回掉
		mBluetoothDeviceAddress = address;
		mConnectionState = STATE_CONNECTING;
		return true;
	}

	/**
	 * Disconnects an existing connection or cancel a pending connection. The
	 * disconnection result is reported asynchronously through the
	 * {@code BluetoothGattCallback#onConnectionStateChange(android.bluetooth.BluetoothGatt, int, int)}
	 * callback.
	 */
	public void disconnect() {
		if (mBluetoothAdapter == null || mBluetoothGatt == null) {
			return;
		}
		mBluetoothGatt.disconnect();
//		try {
//			Thread.sleep(20);
//		} catch (InterruptedException e) {
//			e.printStackTrace();
//		}
//		close();
	}

	private void close() {
		if (mBluetoothGatt == null) {
			return;
		}
		mBluetoothGatt.close();
		mBluetoothGatt = null;
	}

	/**
	 * 返回远程蓝牙设备这关贸总协定客户目标
	 * 
	 * @return
	 */
	private BluetoothDevice getCurDevice() {
		if (mBluetoothGatt == null) {
			return null;
		}
		return mBluetoothGatt.getDevice();
	}

	/**
	 * 判断当前设备连接状态
	 * 
	 * @return STATE_CONNECTED = 2; STATE_CONNECTING = 1; STATE_DISCONNECTED = 0
	 *         ; STATE_DISCONNECTING = 3;
	 */
	public int getConnectState() {
		if (getCurDevice() == null)
			return -1;
		else
			return mBluetoothManager.getConnectionState(getCurDevice(), BluetoothProfile.GATT);

	}
	
	private Intent mIntent;
	
	private void initReceiver(){
		IntentFilter filter = new IntentFilter(WjkConstant.CONNECT_WEIGHT_ACTION_DISCONNECT);
		filter.addAction(WjkConstant.CONNECT_TEMPUT_ACTION_DISCONNECT);
		context.registerReceiver(new ChangeReceiver(), filter);
	}
	
	class ChangeReceiver extends BroadcastReceiver{
		String tag = "血压 util ChangeReceiver";
		@Override
		public void onReceive(Context context, Intent intent) {
			String action = intent.getAction();
			 if (WjkConstant.CONNECT_WEIGHT_ACTION_DISCONNECT.equals(action)){
				mIntent = new Intent(WjkConstant.DISCONNECT_ACTION_TOWEIGHT);
				Log.e(tag, "血压的-------------------------------开始断开连接");
				disconnect();
			}else if (WjkConstant.CONNECT_TEMPUT_ACTION_DISCONNECT.equals(action)) {
				Log.e(tag, "血压的-------------------------------开始断开连接 跳到体温计");
				mIntent = new Intent(WjkConstant.DISCONNECT_ACTION_TOTEMPUT);
				disconnect();
			}
			
		}
	}
}
